package com.hcbd.tdwt.ui.xingyu.fragment;

import static android.content.Context.SENSOR_SERVICE;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.hcbd.tdwt.R;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.hcbd.tdwt.MainApp;

import com.hcbd.tdwt.base.BaseFragment;
import com.hcbd.tdwt.base.BeidouBoxParams;
import com.hcbd.tdwt.base.Constant;
import com.hcbd.tdwt.base.GlobalParams;
import com.hcbd.tdwt.ui.common.dialog.BottomSelectDialog;
import com.hcbd.tdwt.util.BDToGPS;
import com.hcbd.tdwt.util.DateUtils;
import com.hcbd.tdwt.util.SharedPreferencesUtil;
import com.hcbd.tdwt.util.StringUtil;
import com.hcbd.tdwt.ui.xingyu.adapter.AmapInfoWinAdapter;
import com.hcbd.tdwt.ui.xingyu.adapter.MapFriendsAdapter;
import com.hcbd.tdwt.ui.xingyu.vo.BoxContact;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.hcbd.tdwt.ui.xingyu.vo.BoxContact_Table;
import com.hcbd.tdwt.ui.xingyu.vo.UserMessageVO;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.lang.ref.WeakReference;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;

import static java.lang.Thread.sleep;


/**
 * create zzh
 * 星宇地图页fragment
 */
@SuppressLint("NonConstantResourceId")
@EFragment(R.layout.fragment_map_xingyu)
public class MapFragment extends BaseFragment implements MainApp.LocationInfoInterface {
    private static String TAG = "MapFragment";
    //地图
    @ViewById(R.id.map_view)
    MapView mapView;
    //显示当前位置
    @ViewById(R.id.current_location_img)
    ImageView currentLocationImg;
    @ViewById(R.id.download_img)
    ImageView downloadImg;
    @ViewById(R.id.switch_map_layer_img)
    ImageView switchMapType;
    @ViewById
    RecyclerView mapFriendRV;
    @ViewById
    View showView;
    @ViewById(R.id.position_info_tv)
    TextView positionInfoTv;
    @ViewById(R.id.map_time_tv)
    TextView mapTimeTv;
    //地图对象的操作方法与接口
    private AMap aMap;
    //缩放级别
    private int zoom = 16;
    //marker弹框
    private AmapInfoWinAdapter amapInfoWinAdapter;
    private MapFriendsAdapter mapFriendsAdapter;
    private List<BoxContact> contactList;
    private boolean isShow = false;
    private BottomSelectDialog bottomSelectDialog;
    MyHandler myHandler;
    private boolean isInit = false;
    private final String MY_LOCATION_TITLE = "MyLocation";
    private Marker myLocation;  // 当使用单北斗模块定位时系统获取不到定位信息地图无法显示我的位置和标记
    private SensorManager sManager;  // 监听陀螺仪变化改变我的位置角度
    private Sensor mSensorOrientation;

    private static class MyHandler extends Handler {
        public final int REFRESH_STATUS_CODE = 5;
        public final int REFRESH_STATUS_LOCAL_CODE = 6;
        //弱引用，在垃圾回收时，被回收
        WeakReference<MapFragment> fragmentWeakReference;
        MyHandler(MapFragment fragment){
            this.fragmentWeakReference=new WeakReference<>(fragment);
        }
        public void handleMessage(Message msg){
            if (msg.what == REFRESH_STATUS_CODE) {
//                fragmentWeakReference.get().mapTimeTv.setText(DateUtils.getDateLongSerial());
                if(BeidouBoxParams.bdTime==0){
                    fragmentWeakReference.get().mapTimeTv.setText("未知时间");
                } else {
                    fragmentWeakReference.get().mapTimeTv.setText(DateUtils.long2Str(BeidouBoxParams.bdTime));
                }

                Log.i(TAG, "拿到北斗时间："+BeidouBoxParams.bdTime);
            } else if (msg.what == REFRESH_STATUS_LOCAL_CODE) {
//                fragmentWeakReference.get().positionInfoTv.setText(MessageFormat.format("经度:{0}纬度:{1}\n高度:{2}", BeidouBoxParams.gpsLongitude, BeidouBoxParams.gpsLatitude, BeidouBoxParams.gpsAltitude));
                fragmentWeakReference.get().positionInfoTv.setText(MessageFormat.format("经度:{0}\n纬度:{1}", BeidouBoxParams.gpsLongitude, BeidouBoxParams.gpsLatitude));
            }
        }
    }
    @AfterViews
    protected void init() {
        initMsgRegister();
        mapView.onCreate(savedInstanceState);
        //new Handler().postDelayed(() -> initMap(), 2000);
        List<String> list = new ArrayList<>();
        list.add("卫星图");
        list.add("标准图");
        bottomSelectDialog = new BottomSelectDialog(this.getContext(), "选择图层", list, (index, str) -> {
            if (aMap == null) {
                toast("加载中,请稍等");
                return;
            }
            if ("卫星图".equals(str)) {
                aMap.setMapType(AMap.MAP_TYPE_SATELLITE);
            } else {
                aMap.setMapType(AMap.MAP_TYPE_NORMAL);
            }
        });
//        initFriendsAdapter();
        isInit = true;
        // 测试，先
//        positionInfoTv.setText(MessageFormat.format("经度:{0}纬度:{1}高度:{2}", BeidouBoxParams.gpsLongitude, BeidouBoxParams.gpsLatitude, BeidouBoxParams.gpsAltitude));
        positionInfoTv.setText(MessageFormat.format("经度:{0}\n纬度:{1}", BeidouBoxParams.gpsLongitude, BeidouBoxParams.gpsLatitude));
//        positionInfoTv.setText(MessageFormat.format("经度:{0}纬度:{1}\n高度:{2}", "113°55′39.30", "22°44′59.71", "115.855"));
        startTime();
        initMyLocInfo();
        initSensor();
        // 1. 删除黑框相关 2. 位置限高两行 3. 编号+200 4. 铃声重启 5. 保存按键
    }
    private Timer locationTimer;
    public void initMyLocInfo(){
        new Thread(() -> {
            boolean isRun=true;
            while (isRun){
                try{
                    sleep(2000);
                    if(BeidouBoxParams.gpsLatDou != 0){
                        Objects.requireNonNull(getActivity()).runOnUiThread(this::initMap);
                        isRun=false;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();

        // 每5秒更新一次我的位置
        locationTimer = new Timer();
        locationTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if(myLocation==null){
                    LatLng location_earth = BeidouBoxParams.gpsLatDou==0? new LatLng(0.0,0.0) : new LatLng(BeidouBoxParams.gpsLatDou,BeidouBoxParams.gpsLonDou);
                    // 需要修改坐标系
                    LatLng location_mars = BDToGPS.castToOtherPoint(location_earth,1);
                    MarkerOptions markerOptions = new MarkerOptions();
                    markerOptions.title(MY_LOCATION_TITLE);
                    markerOptions.displayLevel(1);
                    markerOptions.position(location_mars);
                    markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.my_location));
                    if(aMap!=null){
                        myLocation = aMap.addMarker(markerOptions);
                    }
//                     MainApp.getInstance().showMsg("没位置");
                } else {
                    myLocation.setVisible(true);
                    // 改变位置
                    LatLng location_earth = BeidouBoxParams.gpsLatDou==0? new LatLng(0.0,0.0) : new LatLng(BeidouBoxParams.gpsLatDou,BeidouBoxParams.gpsLonDou);
                    // 需要修改坐标系
                    LatLng location_mars = BDToGPS.castToOtherPoint(location_earth,1);
                    myLocation.setPosition(location_mars);
//                    MainApp.getInstance().showMsg("系统位置："+BeidouBoxParams.gpsLatDou+"/"+BeidouBoxParams.gpsLonDou+" 当前坐标："+myLocation.getPosition());
                }
            }
        },5000,5000);
    }

    private SensorEventListener sensorEventListener;
    public void initSensor(){
        sManager = (SensorManager) this.getActivity().getSystemService(SENSOR_SERVICE);
        mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        sensorEventListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent sensorEvent) {
                if(sensorEvent.sensor.getType()==Sensor.TYPE_ORIENTATION){
                    float angle = sensorEvent.values[0]*(-1.0f);
//                    Log.i(TAG, "旋转: "+angle );
                    if(myLocation!=null){
                        myLocation.setRotateAngle(angle);
                    }
                }
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int i) {

            }
        };
    }

    @Click
    void currentLocationImg() {
        LatLng location = BDToGPS.castToOtherPoint(new LatLng(BeidouBoxParams.gpsLatDou, BeidouBoxParams.gpsLonDou),1);
        changeCamera(CameraUpdateFactory.newLatLng(location), null, true);
    }

    @Click(R.id.download_img)
    void downloadImg() {
        startActivity(new Intent(this.getContext(), com.amap.api.maps.offlinemap.OfflineMapActivity.class));
    }

    @Click(R.id.switch_map_layer_img)
    void switchMapType() {
        BottomSelectDialog.show(bottomSelectDialog);
    }

    public void initFriendsAdapter() {
        contactList = SQLite.select().from(BoxContact.class).where(BoxContact_Table.boxId.notEq(GlobalParams.commandCentreNumber),
                BoxContact_Table.latitude.isNotNull(),
                BoxContact_Table.longitude.isNotNull(),
                BoxContact_Table.latitude.notEq("0"),
                BoxContact_Table.longitude.notEq("0")
        ).queryList();

        if (mapFriendsAdapter == null) {
            mapFriendsAdapter = new MapFriendsAdapter(this.getContext(), contactList);
            mapFriendsAdapter.setHasStableIds(true);
        } else {
            mapFriendsAdapter.notifyDataSetChanged(contactList);
            return;
        }
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this.getContext(), 1);
        mapFriendRV.setLayoutManager(gridLayoutManager);
        mapFriendRV.setAdapter(mapFriendsAdapter);
        mapFriendsAdapter.setOnItemClickListener(new MapFriendsAdapter.OnItemClickListener() {
            @Override
            public void onPayAttention(BoxContact boxContact) {
                int isPayAttention = boxContact.getIsPayAttention();
                if (isPayAttention == 0) {
                    boxContact.setIsPayAttention(1);
                } else {
                    boxContact.setIsPayAttention(0);
                }
                boxContact.update();
                initFriendsAdapter();
            }

            @Override
            public void onClick(BoxContact boxContact) {
                String latitude = boxContact.getLatitude();
                String longitude = boxContact.getLongitude();
                if (latitude == null || "0".equals(latitude) || longitude == null || "0".equals(longitude)) {
                    toast("当前用户并未发送坐标信息!");
                    return;
                }
                LatLng latLng = BDToGPS.castToOtherLat(new LatLng(StringUtil.stringToDouble(boxContact.getLatitude()), StringUtil.stringToDouble(boxContact.getLongitude())), 1);
                changeCamera(CameraUpdateFactory.newLatLng(latLng), null, true);
                for (Marker marker : markers) {
                    AmapInfoWinAdapter.Info obj = (AmapInfoWinAdapter.Info) marker.getObject();
                    if (boxContact.getBoxId().equals(obj.number)) {
                        marker.showInfoWindow();// 显示信息
                        break;
                    }
                }

            }
        });
    }

    public void clearCenterNumber() {
        for (BoxContact boxContact : contactList) {
            if (GlobalParams.rdCentreNumber.equals(boxContact.getBoxId())) {
                contactList.remove(boxContact);
                return;
            }
        }
    }

    private List<Marker> markers = new ArrayList<>();

    // 初始化标记点
    private void initMarker() {
        markers.clear();
        for (BoxContact boxContact : contactList) {
            String latitude = boxContact.getLatitude();
            String longitude = boxContact.getLongitude();
            if (latitude == null || "0".equals(latitude) || longitude == null || "0".equals(longitude)) {
                continue;
            }
            addMarker(boxContact);
        }
        AmapInfoWinAdapter infoWindowView = new AmapInfoWinAdapter(this.getContext());
        infoWindowView.setInfoWindowViewInterface(new AmapInfoWinAdapter.InfoWindowViewInterface() {
            @Override
            public void onSendMsg(String number) {

            }

            @Override
            public void onDetails(AmapInfoWinAdapter.Info info) {

            }
        });
        aMap.setInfoWindowAdapter(infoWindowView);
    }

    private void addMarker(BoxContact boxContact) {
        LatLng wgsLatlng = new LatLng(StringUtil.stringToDouble(boxContact.getLatitude()), StringUtil.stringToDouble(boxContact.getLongitude()));
        LatLng latLng = BDToGPS.castToOtherPoint(wgsLatlng, 1);
        MarkerOptions markerOption = new MarkerOptions();
        markerOption.position(latLng);
        markerOption.draggable(true);
        Marker marker = aMap.addMarker(markerOption);
        marker.setObject(AmapInfoWinAdapter.build(boxContact));
        markers.add(marker);
    }

    @Override
    public void onSwitch() {
        if (positionInfoTv != null) {
            positionInfoTv.setText(MessageFormat.format("经度:{0}纬度:{1}高度:{2}", BeidouBoxParams.gpsLongitude, BeidouBoxParams.gpsLatitude, BeidouBoxParams.gpsAltitude));
//            initFriendsAdapter();
        }
        MainApp.getInstance().setLocationInfoInterface(this);
    }

    /**
     * 调整缩放级别
     *
     * @param update
     * @param callback
     * @param animated
     */
    private void changeCamera(CameraUpdate update, AMap.CancelableCallback callback, boolean animated) {
        if (aMap == null) {
            toast("加载中,请稍等");
            return;
        }
        if (animated) {
            aMap.animateCamera(update, 500, callback);
        } else {
            aMap.moveCamera(update);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mapView != null) {
            mapView.onDestroy();
        }
        isInit = false;
        if(myHandler!=null){
            myHandler.removeCallbacksAndMessages(null);
        }
        if(locationTimer!=null){
            locationTimer.cancel();
            locationTimer=null;
        }
        if(refreshTimer!=null){
            refreshTimer.cancel();
            refreshTimer=null;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 1)
    public void eventBus(UserMessageVO userMessage) {
//        initFriendsAdapter();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mapView != null) {
            mapView.onResume();
        }
        sManager.registerListener(sensorEventListener, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);
    }


    @Override
    public void onPause() {
        super.onPause();
        if (mapView != null) {
            mapView.onPause();
        }
        if (sManager != null) {
            sManager.unregisterListener(sensorEventListener);
        }
    }

    /**
     * 初始化地图
     */
    private void initMap() {
        if (aMap == null) {
            aMap = mapView.getMap();
        }
        //不显示高德地图默认文字
        aMap.showMapText(true);
        //定义一个UiSettings对象
        UiSettings mUiSettings;
        //实例化UiSettings类对象
        mUiSettings = aMap.getUiSettings();
        //是否显示指南针
        mUiSettings.setCompassEnabled(false);
        //是否显示缩放按钮
        mUiSettings.setZoomControlsEnabled(false);
        //比例尺控件是否显示
        mUiSettings.setScaleControlsEnabled(true);
        //旋转手势关闭
        mUiSettings.setRotateGesturesEnabled(false);
        //是否显示定位到当前位置
        mUiSettings.setMyLocationButtonEnabled(false);
        if (BeidouBoxParams.gpsLatDou == 0) {
            //移动中心点到用户当前位置
            zoom = 3;
        } else {
            //移动中心点到用户当前位置
            zoom = 16;
        }
        // 坐标系转化
        LatLng location = BDToGPS.castToOtherPoint(new LatLng(BeidouBoxParams.gpsLatDou, BeidouBoxParams.gpsLonDou),1);
        aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, zoom));
        aMap.setOnMarkerClickListener(markerClickListener);
//        initMarker();
        //初始化当前位置
//        initAmapLocation();
    }

    // marker 对象被点击时回调的接口
    // 返回 true 则表示接口已响应事件，否则返回false
    AMap.OnMarkerClickListener markerClickListener = marker -> {
        if(marker.getTitle().equals(MY_LOCATION_TITLE)){return true;}
        if (marker.isInfoWindowShown()) {
            marker.hideInfoWindow();
        } else {
            marker.showInfoWindow();
        }
        return true;
    };

    /**
     * 初始化地图定位
     */
    private void initAmapLocation() {
        //初始化定位蓝点样式类
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.strokeColor(getResources().getColor(R.color.colorPrimaryTransparent50));
        myLocationStyle.radiusFillColor(getResources().getColor(R.color.colorPrimaryTransparent50));
        // 设置小蓝点的图标，在xml文件中控制大小
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromView(getActivity().getLayoutInflater().inflate(R.layout.map_marker_current_location_layout, null)));
        // 连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。
        //（1秒1次定位）如果不设置myLocationType，默认也会执行此种模式。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
        //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
        myLocationStyle.interval(2000);
        //设置定位蓝点的Style
        aMap.setMyLocationStyle(myLocationStyle);
        //设置默认定位按钮是否显示，非必需设置。
        //aMap.getUiSettings().setMyLocationButtonEnabled(true);
        //设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false。
        aMap.setMyLocationEnabled(true);

    }

    @Click
    void showView() {
        if (isShow) {
            mapFriendRV.setVisibility(View.GONE);
            isShow = false;
        } else {
            isShow = true;
            mapFriendRV.setVisibility(View.VISIBLE);
        }
    }

    private Timer refreshTimer = new Timer();
    private TimerTask task;

    // 刷新时间
    public void startTime() {
        myHandler=new MyHandler(this);
        task = new TimerTask() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.what = myHandler.REFRESH_STATUS_CODE;
                myHandler.sendMessage(msg);
            }
        };
        refreshTimer.schedule(task, 1000, 1000);
    }

    @Override
    public void LocationInfo() {
        if(isInit){
            Message msg = new Message();
            msg.what = myHandler.REFRESH_STATUS_LOCAL_CODE;
            myHandler.sendMessage(msg);
        }
    }
}
